﻿//#pragma warning(disable: VCR102); // 关闭 Visual Studio 2010 的警告
#pragma once

class VertexBuffer
{	// 顶点缓冲区类
private:
	int m_id;
	unsigned int m_vertex_renderer_id;
public:
	VertexBuffer() = default;
	VertexBuffer(const void* data, unsigned int size, uint32_t id = 1);

	~VertexBuffer();

	void bind() const;
	void unbind() const;
};

class IndexBuffer
{	// 索引缓冲区类
private:
	int m_id;
	unsigned int m_index_renderer_id;
	unsigned int m_index_count;
public:
	IndexBuffer() = default;
	IndexBuffer(const unsigned int* data, unsigned int count, uint32_t id = 1);

	~IndexBuffer();

	void bind() const;
	void unbind() const;
	inline unsigned int get_index_id() const { return m_index_renderer_id; } // 获取索引缓冲区ID
	inline unsigned int get_count() const { return m_index_count; } // 获取索引数量
};

struct VertexBufferElement
{	// 顶点缓冲区元素结构体
	unsigned int  type;			// 元素类型
	unsigned int  count;		// 元素数量
	unsigned char normalized;	// 是否归一化
	//unsigned int  offset;		// 偏移量
	//unsigned int  stride;		// 步长

	static unsigned int get_type_size(unsigned int type) {
		switch (type) {
		case GL_FLOAT:			return 4; // sizeof(GLfloat)
		case GL_UNSIGNED_INT:	return 4; // sizeof(GLuint)
		case GL_UNSIGNED_BYTE:	return 1; // sizeof(GLubyte)
		}
		gl_assert(false); // 未知类型，直接打断运行
		return 0;
	}
};

class VertexBufferLayout
{	// 顶点缓冲区布局类
private:
	std::vector<VertexBufferElement> m_elements;
	unsigned int					 m_stride;
	//unsigned int					 m_stride;
public:
	VertexBufferLayout()
		: m_stride(0) {
	}
	// VertexBufferLayout(const std::initializer_list<VertexBufferElement>& elements); // 初始化列表构造函数 istd::nitializer_list 用于存储类型列表

	template<typename Ty>
	void push(unsigned int count, bool normalized = false) {
		static_assert(false, "Type is not supported!");
	}

	template<>
	void push<float>(unsigned int count, bool normalized) { // 建议传入的 normalized 值使用 false
		m_elements.push_back({ GL_FLOAT, count, normalized });
		m_stride += VertexBufferElement::get_type_size(GL_FLOAT) * count;
	}

	template<>
	void push<unsigned int>(unsigned int count, bool normalized) { // 建议传入的 normalized 值使用 true
		m_elements.push_back({ GL_UNSIGNED_INT, count, normalized });
		m_stride += VertexBufferElement::get_type_size(GL_UNSIGNED_INT) * count;
	}

	template<>
	void push<unsigned char>(unsigned int count, bool normalized) { // 建议传入的 normalized 值使用 true
		m_elements.push_back({ GL_UNSIGNED_BYTE, count, normalized });
		m_stride += VertexBufferElement::get_type_size(GL_UNSIGNED_BYTE) * count; // 注意：这里的 count 指的是元素数量，而不是字节数
	}

	/*template<typename Ty>
	void push(unsigned int type, unsigned int count, bool normalized = false) {
		m_stride += sizeof(Ty);
	} */

	inline const std::vector<VertexBufferElement>& get_elements() const { return m_elements; }
	inline unsigned int get_stride() const { return m_stride; }
};

class VertexArray
{	// 顶点数组类
private:
	unsigned int m_id;
	unsigned int m_vertex_array_renderer_id;
public:
	VertexArray() = default;
	VertexArray(unsigned int id = 1);
	~VertexArray();

	void bind() const;
	void unbind() const;

	void add_buffer(const VertexBuffer& vb, const VertexBufferLayout& layout, unsigned int offset = 0);
	unsigned int& get_vertex_array_id() { return m_vertex_array_renderer_id; } // 获取顶点数组ID
};

